package com.shanpin.shebao.admin.employee;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import com.shanpin.shebao.admin.module.shebao.SBConfigService;
import com.shanpin.shebao.admin.module.shebao.model.ShebaoConfigData;
import com.shanpin.shebao.admin.order.PayedDao;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.shanpin.core.constant.OptConst;
import com.shanpin.core.constant.OrderConst;
import com.shanpin.core.constant.OrderLogConst;
import com.shanpin.core.constant.PayType;
import com.shanpin.core.utils.DateUtil;
import com.shanpin.shebao.admin.db.AdminDbRepository;
import com.shanpin.shebao.admin.db.AppDbRepository;
import com.shanpin.shebao.admin.module.city.CityCacheService;
import com.shanpin.shebao.admin.module.shebao.SBConfigDao;
import com.shanpin.shebao.admin.module.shebao.model.SheBaoConfigDataItem;
import com.shanpin.shebao.admin.order.PayedDetailDao;
import com.shanpin.shebao.constant.QueryOperation;
import com.shanpin.shebao.dao.SBUserDao;
import com.shanpin.shebao.model.City;
import com.shanpin.shebao.model.Employee;
import com.shanpin.shebao.model.EmployeeDetail;
import com.shanpin.shebao.model.PayOrderDetail;
import com.shanpin.shebao.model.SBUser;
import com.shanpin.shebao.model.ServiceResult;
import com.shanpin.shebao.result.CityResult;
import com.shanpin.shebao.utility.Criterition;
import com.shanpin.shebao.utility.MoreCriteria;
import com.shanpin.shebao.utility.PageModel;

@Repository
public class EmployeeDao {
	
	private final static Logger LOG = LoggerFactory.getLogger(EmployeeDao.class);

/*	private static final String QUERY_DETAIL_SQL = "SELECT e.*,p.order_no, p.pay_no, p.pay_uid, p.channels, p.prices, p.pay_for, " +
			"p.pay_time, p.funds, p.pay_status, pu.id_card, pu.user_name, pu.cid, p.for_month, pu.phone, pu.nation, pu.gender, " +
			"pu.hukou, pu.recon_result, p.new_card, p.isAuto, su.id_card_img, su.shebao_card " +
			"FROM t_sb_employee e " +
			"inner join t_sb_order_pay p on p.order_no=e.order_no " +
			"inner join t_sb_order pu on e.order_no=pu.order_no " +
			"inner join t_sb_user su on su.id_card=e.id_card";*/
	
	private static final String QUERY_DETAIL_SQL = "SELECT e.* FROM t_sb_employee e";
	
	@Autowired
	private PayedDetailDao payOrderDetailDao;
	
	@Autowired
	private SBUserDao sbUserDao;
	
	@Autowired
	private AdminDbRepository admin;

	@Autowired
	private CityCacheService cityCacheService;
	@Autowired
	private SBConfigDao sbConfigDao;
	@Autowired
	private EmployeeStopDao employeeStopDao;
	
	@Autowired
	private AppDbRepository app;

	@Autowired
	private PayedDao payedDao;

	@Autowired
	private SBConfigService sbConfigService;


	public int getTotalRecord(MoreCriteria c){
		
		Long count = 0L;

//		String sql = "SELECT COUNT(1) FROM t_sb_employee e inner join t_sb_order pu on e.order_no=pu.order_no inner join t_sb_order_pay p on p.order_no=pu.order_no";
		String sql = "SELECT COUNT(1) FROM t_sb_employee e";
		
		//是否查询月份
		sql = checkCriteria(c, sql);
		
		count = admin.queryLong(sql, c.getValueList().toArray());
		
		return count.intValue();
		
	}
	

	/**
	 * 添加员工记录
	 * @param employee
	 * @return
	 */
	public boolean add(Employee employee) {
		String sql = "INSERT INTO t_sb_employee(pay_uid, order_no, id_card, pay_for, pay_type, for_month, gen_time) VALUES (?,?,?,?,?,?,?)";
		Date d = new Date();
		boolean ret = admin.update(sql, employee.getPay_uid(), employee.getOrder_no(), employee.getId_card(), employee.getPay_for(), employee.getPay_type(), employee.getFor_month(), d);
		return ret;
	}

	public PageModel queryPage(int pageNo, int pageSize, MoreCriteria<String, Criterition> c) {
		PageModel pm = new PageModel();
//		String queryString = this.getCacheKey(pageNo, pageSize, c);
//		List<EmployeeDetail> detailList = CACHE.getIfPresent(queryString);
//		if (null == detailList) {
//			detailList = queryPageData(pageNo, pageSize, c, pm);
//			if (!detailList.isEmpty() && pageSize < 300) {
//				CACHE.put(queryString, detailList);
//			}
//		}
		List<EmployeeDetail> detailList = queryPageData(pageNo, pageSize, c, pm);
		pm.setPageNo(pageNo);
		pm.setPageSize(pageSize);
		pm.setRecordList(detailList);
		pm.setTotalRecord(getTotalRecord(c));
		return pm;
	}

	/**
	 * 根据条件查询员工列表
	 * @return
	 */
	protected List<EmployeeDetail> queryPageData(int pageNo, int pageSize, 
			MoreCriteria<String, Criterition> c, PageModel pm) {
		String sql = checkCriteria(c, QUERY_DETAIL_SQL);
		sql = sql + " order by gen_time desc, order_no asc";	//TODO order_no 排序规则待优化
		sql = pm.getMySQLPageSQL(sql, (pageNo-1)*pageSize, pageSize);
		
		List<Employee> recordList = admin.query(sql, pageSize, Employee.detailMapper, c.getValueList().toArray());
		
		List<EmployeeDetail> detailList = new ArrayList<EmployeeDetail>(recordList.size());
		EmployeeDetail detail = null;
		for(Employee e: recordList) {
			PayOrderDetail payOrderDetail = payOrderDetailDao.queryDetailBy(e.getOrder_no());
			if(payOrderDetail == null ) {
				LOG.error("NOT FOUND payedOrder:{}", e.getOrder_no());
				continue;
			}
			detail = new EmployeeDetail();
			assignPayOrderToDetail(detail, payOrderDetail);
			assignEmployeeToDetail(e, detail);
							
			SBUser sbUser = sbUserDao.getSBUser(e.getPay_uid(), e.getId_card());
			detail.setShebao_card(null == sbUser ? "" : sbUser.getShebao_card());
			detail.setFund_card(null == sbUser ? "" : sbUser.getFund_card());
			detail.setHk_address(null == sbUser ? "" : sbUser.getHk_address());
			detail.setEducation(null == sbUser ? "" : sbUser.getEducation());
			
			detailList.add(detail);
		}
		return detailList;
	}


	private String checkCriteria(MoreCriteria c, String sql) {
		boolean monthQuery = false;
		String for_month = "";
		Set<Entry<String, Criterition>> entries = c.getPair().entrySet();
		if(entries != null && entries.size() > 0) {
			
			for(Iterator<Entry<String, Criterition>> iter = entries.iterator(); iter.hasNext();) {
				Entry<String, Criterition> en = iter.next();
				if(en != null && "for_month".equals(en.getKey())) {
					monthQuery = true;
					for_month = ((Criterition)c.getPair().get("for_month")).getExpectValue();
					iter.remove();
				}
			}
		}
		sql = sql + c.getSqlString();
		
		//如果查询月份,就把手动增员的也查出来
		if(monthQuery) {
			if(StringUtils.isNotBlank(for_month)) {
				if(c.getPair().entrySet() != null && c.getPair().entrySet().size() > 0) {
					sql = sql + " and ";
				} else {
					sql = sql + " where ";
				}
				sql = sql + " ((for_month = " + for_month + " and added_month is null) "
						+ "or (added_month = " + for_month + "))";
			}
			Criterition criterition = new Criterition("e.for_month", for_month.trim(), QueryOperation.EQ, QueryOperation.AND);
			c.getPair().put("for_month", criterition);
		} 
		
		return sql;
	}


	private void assignEmployeeToDetail(Employee e, EmployeeDetail detail) {
		detail.setFor_month(e.getFor_month());
		detail.setGen_time(e.getGen_time());
		detail.setId_card(e.getId_card());
		detail.setHukou(e.getHukou_type());
		detail.setCity_code(e.getCity_code());
		detail.setOrder_no(e.getOrder_no());
		detail.setPay_for(e.getPay_for());
		detail.setPay_type(e.getPay_type());
		detail.setPay_uid(e.getPay_uid());
		detail.setRecon_result(e.getRecon_result());
		detail.setAny_reason(e.getAny_reason());
		detail.setStatus(e.getStatus());
		detail.setCardOpt(e.getNew_card());
		detail.setAdded_month(e.getAdded_month());
		detail.setNew_card(e.getNew_card());
		detail.setId_card_status(e.getId_card_status());
		detail.setId_card_desc(e.getId_card_desc());
	}


	private void assignPayOrderToDetail(EmployeeDetail detail,
			PayOrderDetail payOrderDetail) {
		detail.setCid(payOrderDetail.getCid());
		detail.setParam_name(payOrderDetail.getParam_name());
		detail.setInc_date(payOrderDetail.getInc_date());
		detail.setDec_date(payOrderDetail.getDec_date());
		detail.setUser_name(payOrderDetail.getUser_name());
		detail.setGender(payOrderDetail.getGender());
		detail.setNation(payOrderDetail.getNation());
		detail.setPhone(payOrderDetail.getPhone());
		
		detail.setPay_for(payOrderDetail.getPay_for());
		detail.setShebaos(payOrderDetail.getShebaos());
		detail.setShebao_charge(payOrderDetail.getShebao_charge());
		detail.setCard_charge(payOrderDetail.getCard_charge()
				.subtract(BigDecimal.valueOf(payOrderDetail.getRefund_card_charge())));
		detail.setTotal_fee(payOrderDetail.getTotal_fee());
		detail.setPre_charge(payOrderDetail.getPre_charge());
		if (payOrderDetail.getDisabled_price().doubleValue() < 1) {
			SheBaoConfigDataItem sbData = sbConfigDao.getShebaoData(payOrderDetail.getCid(), payOrderDetail.getHukou());
			detail.setDisabled(BigDecimal.valueOf(sbData.getDisabled()));
		} else {
			detail.setDisabled(payOrderDetail.getDisabled_price());
		}
		
		detail.setPay_status(payOrderDetail.getStatus());
		detail.setOrder_month(payOrderDetail.getFor_month());
		
		detail.setFunds(payOrderDetail.getFunds());
		detail.setFund_charge(payOrderDetail.getFund_charge());
		detail.setFundDataItem(payOrderDetail.getFundDataItem());
		detail.setFund_salary(payOrderDetail.getFund_salary());
		
		detail.setNote(payOrderDetail.getNote());
		detail.setRefundAmount(payOrderDetail.getRefundAmount());
		detail.setRefundCharge(BigDecimal.valueOf(payOrderDetail.getRefund_charge()));
		detail.setRefundReason(payOrderDetail.getRefundReason());
		detail.setRefundType(payOrderDetail.getRefundType());
		detail.setRepayAmount(payOrderDetail.getRepayAmount());
		detail.setRepayReason(payOrderDetail.getRepayReason());
		detail.setRepayType(payOrderDetail.getRepayType());
		detail.setNeedRepayAmount(payOrderDetail.getNeedRepayAmount());

		detail.setCoupon_code(payOrderDetail.getCoupon_code());
		detail.setCoupon_price(payOrderDetail.getCoupon_price());
		detail.setCoupon_type(payOrderDetail.getCoupon_type());
		
		detail.setSb_wage(payOrderDetail.getSb_wage());
		detail.setWage_status(payOrderDetail.getWage_status());
	}


	public EmployeeDetail queryDetailBy(String order_no, String month) {
		String sql = QUERY_DETAIL_SQL;
//		sql = sql + " where order_no = ? and for_month = ?";
		sql = sql + " where order_no=?";
		
		Employee e = admin.queryT(sql, Employee.detailMapper, order_no);
		
		if(e != null) {
			EmployeeDetail detail = new EmployeeDetail();
			assignEmployeeToDetail(e, detail);
			
			PayOrderDetail payOrderDetail = null;
//			if(0 == e.getPay_type()) {
//				payOrderDetail = payOrderDetailDao.queryDetailByBuyNo(e.getOrder_no(), e.getFor_month() + "");
//				
//			} else {
//				payOrderDetail = payOrderDetailDao.queryDetailBy(e.getOrder_no());
//				
//			}
			
			payOrderDetail = payOrderDetailDao.queryDetailBy(e.getOrder_no());
			
			if(payOrderDetail != null) {
				assignPayOrderToDetail(detail, payOrderDetail);
			}
			
			SBUser sbUser = sbUserDao.getSBUser(e.getPay_uid(), e.getId_card());
			if(sbUser != null) {
				detail.setShebao_card(sbUser.getShebao_card());
				detail.setFund_card(sbUser.getFund_card());
			}
			
			return detail;
		}
		
		return null;
	}
	
	public Employee queryDetailBy(String order_no) {
		String sql = QUERY_DETAIL_SQL;
		sql = sql + " where e.order_no = ?";
		
		Employee e = admin.queryT(sql, Employee.detailMapper, order_no);
		
		return e;
	}

	/**
	 *
	 * @param idCard 参保人身份证
	 * @param forMonth	参保月份
	 * @param cityCode	城市代码
	 * @return
	 */
	public Employee queryDetailBy(String idCard,int forMonth,int cityCode,int pay_for) {
		String sql = QUERY_DETAIL_SQL;
		sql = sql + " WHERE e.id_card = ? AND e.for_month = ? AND city_code = ? "
				+ " AND pay_for = ?";

		Employee e = admin.queryT(sql, Employee.detailMapper, idCard,forMonth,cityCode,pay_for);

		return e;
	}
	
	public boolean updateReconStatus(EmployeeDetail employeeDetail) {
		String sql = "update t_sb_employee set recon_result = ?";
		sql = sql + " where order_no = ? and for_month = ?";
		boolean result = admin.update(sql, employeeDetail.getRecon_result(), employeeDetail.getOrder_no(), employeeDetail.getFor_month());
		PayOrderDetail payOrderDetail = payOrderDetailDao.queryDetailBy(employeeDetail.getOrder_no());
		if(payOrderDetail == null) {
			return result;
		}
		if(1 == employeeDetail.getRecon_result()) { // 代理员工审核通过一致时
				payOrderDetail.setStatus(OrderConst.OK.getNum());
				
				payOrderDetailDao.updateStatus(payOrderDetail, "");
			
		} else if(2 == employeeDetail.getRecon_result()) { // 代理员工审核不一致时
			if(OrderConst.OK.getNum() != payOrderDetail.getStatus()) { // 当订单状态为成功时，不允许再改回
				payOrderDetail.setStatus(OrderConst.FAIL.getNum());
				payOrderDetail.setFor_month(employeeDetail.getFor_month());
				payOrderDetailDao.updateStatus(payOrderDetail, "");
			}
		} 
		afterUpdated();
		return result;
	}


	public boolean updateReason(EmployeeDetail employeeDetail) {
		String sql = "update t_sb_employee set any_reason = ?";
		sql = sql + " where order_no = ?";
		boolean result = admin.update(sql, employeeDetail.getAny_reason(), employeeDetail.getOrder_no());
		afterUpdated();
		return result;
	}


	public boolean updateShebaoCard(EmployeeDetail employeeDetail) {
		String sql = "update t_sb_user set shebao_card = ?";
		sql = sql + " where id_card = ?";
		boolean result = app.update(sql, employeeDetail.getShebao_card(), employeeDetail.getId_card());

		afterUpdated();
		return result;
	}


	/**
	 * 更改增减员状态
	 * @param employeeDetail
	 * @return
	 */
	public boolean updateStatus(EmployeeDetail employeeDetail) {
		String sql = "update t_sb_employee set status = ?";
		sql = sql + " where order_no = ?";
		boolean result = admin.update(sql, employeeDetail.getStatus(), employeeDetail.getOrder_no());
		
		if(1 == employeeDetail.getStatus() && 0 == employeeDetail.getPay_type()) { // 增员改为成功状态
			PayOrderDetail payOrderDetail = payOrderDetailDao.queryDetailBy(employeeDetail.getOrder_no());
			
			if(payOrderDetail != null) {
				payOrderDetail.setStatus(OrderConst.OK.getNum());
				
				payOrderDetailDao.updateStatus(payOrderDetail, "");
			}
			
		} else if(2 == employeeDetail.getStatus() && 0 == employeeDetail.getPay_type()) { // 增员改为失败状态时
			PayOrderDetail payOrderDetail = payOrderDetailDao.queryDetailBy(employeeDetail.getOrder_no());
			
			if(payOrderDetail != null && OrderConst.OK.getNum() != payOrderDetail.getStatus()) { // 当订单状态为成功时，不允许再改回
				payOrderDetail.setStatus(OrderConst.FAIL.getNum());
				
				payOrderDetail.setFor_month(employeeDetail.getFor_month());
				payOrderDetailDao.updateStatus(payOrderDetail, employeeDetail.getAny_reason());
			}
			
		} 

		afterUpdated();
		return result;
	}


	protected List<Integer> queryAddCityCode(String month) {
		String sql = "SELECT DISTINCT city_code FROM t_sb_employee WHERE pay_type = 0 AND ((for_month=? AND added_month is null) OR added_month=?)";
		List<Integer> recordList = admin.queryForList(sql, Integer.class, month, month);
		return recordList;
	}
//	public List<City> queryAddCities(String month) {
//		
//		List<City> recordList;
//		if(month != null) {
//			String sql = "SELECT DISTINCT city_code FROM t_sb_employee where pay_type = 0"
//					+ " AND ((for_month=? AND added_month is null) OR added_month=?)";
//			recordList = admin.query(sql, City.codeMapper, month, month);
//		} else {
//			String sql = "SELECT DISTINCT city_code FROM t_sb_employee";
//			recordList = admin.query(sql, City.codeMapper);
//		}
//		
//		if(recordList != null && recordList.size() > 0) {
//			for(City city: recordList) {
//				City c = cityService.get(city.getCity_code());
//				if(c != null) {
//					BeanUtils.copyProperties(c, city);
//				}
//			}
//		}
//		
//		return recordList;
//	}


	public List<CityResult> queryCutWarnCities(String day) {
		
		List<CityResult> recordList;
		if(day != null) {
			String sql = "SELECT city_code, dec_date FROM t_sb_city where dec_date <= ? and dec_date >0 AND added_cid=0 order by dec_date asc";
			recordList = app.query(sql, CityResult.decDayMapper, day);
		} else {
			String sql = "SELECT city_code, dec_date FROM t_sb_city WHERE added_cid=0";
			recordList = app.query(sql, CityResult.decDayMapper);
		}
		
		if(recordList != null && recordList.size() > 0) {
			for(CityResult city: recordList) {
				City c = cityCacheService.get(city.getCity_code());
				if(c != null) {
					BeanUtils.copyProperties(c, city);
				}
			}
		}
		
		return recordList;
	}
	
	public List<CityResult> queryAddWarnCities(String day) {
		
		List<CityResult> recordList;
		if(day != null) {
			String sql = "SELECT city_code, inc_date FROM t_sb_city where inc_date <= ? and inc_date >0 AND added_cid=0 order by inc_date asc";
			recordList = app.query(sql, CityResult.incDayMapper, day);
		} else {
			String sql = "SELECT city_code, inc_date FROM t_sb_city WHERE added_cid=0";
			recordList = app.query(sql, CityResult.incDayMapper);
		}
		
		if(recordList != null && recordList.size() > 0) {
			for(CityResult city: recordList) {
				City c = cityCacheService.get(city.getCity_code());
				if(c != null) {
					BeanUtils.copyProperties(c, city);
				}
			}
		}
		
		return recordList;
	}


	public List<Integer> queryExistedCities(String month) {
		List<Integer> recordList;
		if(month != null) {
			String sql = "SELECT DISTINCT city_code FROM t_sb_employee where ((for_month=? AND added_month is null) OR added_month=?)";
			recordList = admin.queryForList(sql, Integer.class, month, month);
		} else {
			String sql = "SELECT DISTINCT city_code FROM t_sb_employee";
			recordList = admin.queryForList(sql, Integer.class);
		}
		
//		if(recordList != null && recordList.size() > 0) {
//			for(City city: recordList) {
//				City c = cityCacheService.get(city.getCity_code());
//				if(c != null) {
//					BeanUtils.copyProperties(c, city);
//				}
//			}
//		}
		
		return recordList;
	}
	
	
	/**
	 * 只加载元表t_sb_employee的数据
	 * @param id_card
	 * @param for_month
	 * @param pay_for
	 * @return
	 */
	public Employee get(String id_card, int for_month, int pay_for) {
		String sql = "SELECT * FROM t_sb_employee WHERE"
				+ " for_month=? AND id_card=? AND pay_for=? LIMIT 1";
		return admin.queryT(sql, Employee.detailMapper, for_month, id_card, pay_for);
	}
	public Employee getNewEmployee(String id_card, int for_month, int pay_for) {
		String sql = "SELECT * FROM t_sb_employee WHERE for_month=?"
				+ " AND id_card=? AND pay_for=? AND pay_type=? LIMIT 1";
		return admin.queryT(sql, Employee.detailMapper, for_month, 
				id_card, pay_for, PayType.FIRST.getKey());
	}
	
	public Employee get(String order_no) {
		String sql = "SELECT * FROM t_sb_employee WHERE order_no=?";
		return admin.queryT(sql, Employee.detailMapper, order_no);
	}
	
	@Transactional
	public ServiceResult<Boolean> handEmployee(Employee handE, String opt_user, int opt_num) {
		Employee e = get(handE.getOrder_no());
		boolean r = false;
		if(null == e) {
			r = addEmployee(handE, opt_user);
		} else {
			r = updateHandAdded(e, handE.getPay_type(), 
					handE.getAdded_month(), opt_user);
		}
		if (!r) {
			return ServiceResult.valueOf("更新参保数据 未成功。");
		}
		// #179 手动增员选择的是在保时，下月是增员，修改为在保。本月已经减员，删除减员。
		if (handE.getPay_type() == PayType.PROXY.getKey()) {
			String ret = afterHandProxyEmployee(handE, opt_num, opt_user);
			return ServiceResult.valueOf(ret, r);
		}
		return ServiceResult.valueT(r);
	}
	
	/**
	 * 添加员工记录
	 * @param employee
	 * @return
	 */
	private boolean addEmployee(Employee e, String opt_user) {
		String sql = "INSERT INTO t_sb_employee (order_no, pay_uid, id_card, "
				+ "city_code, hukou_type, pay_for, "
				+ "pay_type, for_month, gen_time, "
				+ "added_month, new_card, status) VALUES (?,?,?, ?,?,?, ?,?,?, ?,?,?)";
		boolean r = admin.update(sql, e.getOrder_no(), e.getPay_uid(), e.getId_card(), 
				e.getCity_code(), e.getHukou_type(), e.getPay_for(), 
				e.getPay_type(), e.getFor_month(), new Date(), 
				e.getAdded_month(), e.getNew_card(), e.getStatus());
		if (r) {
			afterUpdated();
			payOrderDetailDao.orderLog(e.getOrder_no(), OrderLogConst.MANAGER_OPT,
					opt_user, "手动增员到"+e.getAdded_month()+"操作");
		}
		return r;
	}
	
	/**
	 * 更新手动增员的信息
	 * @param order_no
	 * @param pay_type
	 * @param added_month
	 * @return
	 */
	private boolean updateHandAdded(Employee e, int pay_type, 
			int added_month, String opt_user) {
		String sql = "UPDATE t_sb_employee SET pay_type=?, added_month=? WHERE order_no=?";
		boolean r = admin.update(sql, pay_type, added_month, e.getOrder_no());
		if (r) {
			afterUpdated();
			String c = "手动增员更新：pay_type:"+e.getPay_type()+"-->"+pay_type
					+"  added_month:"+e.getAdded_month()+"-->"+added_month;
			payOrderDetailDao.orderLog(e.getOrder_no(), OrderLogConst.MANAGER_OPT,
					opt_user, c);
		}
		return r;
	}
	
	private String afterHandProxyEmployee(Employee handE, int opt_num, String optUser) {
		String result = "";
		// 通过操作月份找下个月的代理记录
		int for_month = DateUtil.yyyyMM(String.valueOf(handE.getAdded_month()), 1);
		Employee eNext = getNewEmployee(handE.getId_card(), for_month, handE.getPay_for());
		if (null != eNext) {
			admin.update("UPDATE t_sb_employee SET pay_type=? WHERE order_no=?", 
					PayType.PROXY.getKey(), eNext.getOrder_no());
			result = "已自动将"+DateUtil.cnMonth(for_month)+"的记录由增员改为在保. <br>";
			LOG.warn("idcard={} {}", handE.getId_card(), result);

			payOrderDetailDao.orderLog(eNext.getOrder_no(), OrderLogConst.MANAGER_OPT,
					optUser, handE.getFor_month()+"的手动在保，"+for_month+"记录由增员改成了在保");
		}
		// 删除指定操作月份的减员, 增当月、减下月规则下，减员是在操作月份的前一个月
		int stop_month =  (opt_num == OptConst.INC_C_DEC_N.getNum()) ? DateUtil.yyyyMM(String.valueOf(handE.getAdded_month()), -1)
				: handE.getAdded_month();
		LOG.warn("idcard={}  eNext_month={}  stop_month={}", handE.getId_card(), for_month, stop_month);
		boolean ret = employeeStopDao.delete(handE.getId_card(),
				stop_month, handE.getPay_for(), handE.getCity_code());
		if (ret) {
			result = result + "已删除"+DateUtil.cnMonth(stop_month)+"的减员记录.";
		} else {
			LOG.warn("idcard={} {}", handE.getId_card(), "！！！ 未成功清除减员记录！！！");
		}
		afterUpdated();
		return result;
	}

	/**
	 * 新办社保卡的状态
	 * @param order_no
	 * @param status
	 * @return
	 */
	public boolean updateNewCardOpt(String order_no, int status) {
		afterUpdated();
		String sql = "UPDATE t_sb_employee SET new_card=? WHERE order_no=?";
		return admin.update(sql, status, order_no);
	}
	

	/**
	 * 订单所有退款，需要对增员、代理员工做处理。<br>
	 * （1）增员的全额退款：若增员已生成，需删除其增员记录，若增员没有生成，则无需生成其增员记录；<br>
	 * （2）参保员工的全额退款：若参保员工已经生成，删除其参保员工的记录，并生成减员名单；
	 * 		若参保员工还没有生成，则无需生成其参保记录，生成减员名单。<br>
	 * （3）若上个月的增员记录或者参保员工记录已经被删除，则本月若有新订单，正常产生增员名单。
	 * @param order_no
	 * @param opt_num  操作规则 代码
	 * @param optMonth 操作月份
	 * @param decMonth 减员月份
	 * @param dec_date 减员截止日期
	 * @return
	 */
	public boolean afterRefundedAll(String order_no, int opt_num, String opt_user,int dec_date) {
		Employee e = queryDetailBy(order_no);
		// 增当月，减下月
		if(e == null && OptConst.INC_C_DEC_N.getNum() == opt_num){
			//查找上个月订单是否有再保订单，如果有上个月在保数据则生成减员数据
			PayOrderDetail order = payOrderDetailDao.queryDetailBy(order_no);
			Employee lastMonthE = queryDetailBy(order.getId_card(),DateUtil.yyyyMM(order.getFor_month()+"",-1),
					order.getCity_code(),order.getPay_for());
			if(lastMonthE == null){
				return true;
			}
			//模拟生成该订单在保数据用于后续生成减员数据
			e = new Employee();
			e.setCity_code(order.getCity_code());
			e.setFor_month(order.getFor_month());
			e.setOrder_no(order_no);
			e.setPay_uid(order.getPay_uid());
			e.setId_card(order.getId_card());
			e.setHukou_type(order.getHukou());
			e.setPay_for(order.getPay_for());
			e.setPay_type(PayType.PROXY.getKey());
		}else if(e == null) {
			return true;
		}
		String sql = "DELETE FROM t_sb_employee WHERE order_no=?";
		boolean r = admin.update(sql, order_no);
		LOG.warn("refund-all order={}, payType={}", e.getOrder_no(), 0==e.getPay_type()?"增员":"在保");
		if(OptConst.INC_C_DEC_N.getNum() == opt_num && !r){
			r = e.getPay_type() == PayType.PROXY.getKey() ? true : false;
		}
		// 在保
		if (r && e.getPay_type() == PayType.PROXY.getKey()) {
			int manual = payOrderDetailDao.queryManual(order_no);
			//如果为手动增员/在保订单，需要检查是否已经过了截止日期
			if(manual > 0){
				int date = Integer.parseInt(DateUtil.currentStr("yyyyMMd"));

				int decDate = 0;
				if(opt_num == OptConst.INC_C_DEC_C.getNum() ){
					//增减当月，手动在保月份 > 当前时间则不做减员
					decDate = Integer.parseInt(manual + "" + dec_date);
				}else{
					//增减下月，增当减下，手动在保月份-1个月>当前时间 或 则不做减员
					decDate = Integer.parseInt(DateUtil.yyyyMM(manual + "", -1) + "" + dec_date);
				}
				if(decDate > date){
					return r;
				}
			}
			String buy_no = app.queryString("SELECT buy_no FROM t_sb_buy_order WHERE order_no=?", e.getOrder_no());
			employeeStopDao.addDecAfterRefunded(e, buy_no, opt_num, opt_user);
		}
		afterUpdated();
		return r;
	}

	
	public boolean batchStatus(String order_no, int status, String any_reason, String opt_user) {
		PayOrderDetail payOrderDetail = payOrderDetailDao.queryDetailBy(order_no);
		if (null == payOrderDetail) {
			LOG.error("updateStatus NOT FOUND order:{}", order_no);
			return false;
		}
		String sql = "update t_sb_employee set status = ?, any_reason=? where order_no = ?";
		boolean r = admin.update(sql, status, any_reason, order_no);
		if (r) {
			afterUpdated();
			int oldStatus = payOrderDetail.getStatus();
			payOrderDetail.setStatus(status);
			payOrderDetailDao.updateStatus(payOrderDetail, any_reason);
			payOrderDetailDao.orderLog(order_no, OrderLogConst.MANAGER_OPT, opt_user, 
					"批量更改状态："+oldStatus+"-->"+status+". "+any_reason);
		}
		return r;
	}
	
	

	
	private String getCacheKey(int pageNo, int pageSize, MoreCriteria<String, Criterition> c) {
		StringBuilder b = new StringBuilder();
		for (Entry<?, ?> entry : c.getPair().entrySet()) {
			b.append(entry.getKey()+":"+((Criterition)entry.getValue()).getExpectValue());
		}
		b.append(pageNo+":"+pageSize);
		return b.toString();
	}
	
	private void afterUpdated() {
//		CACHE.invalidateAll();
//		CACHE.cleanUp();  // 引方法清除不了缓存里的数据
	}
	
//	private final Cache<String, List<EmployeeDetail>> CACHE = CacheBuilder.newBuilder()
//			.expireAfterWrite(5, TimeUnit.MINUTES).maximumSize(25)
//			.build();
}
